///import core
///commands 查找替换
///commandsName  SearchReplace
///commandsTitle  查询替换
///commandsDialog  dialogs\searchreplace
/**
 * @description 查找替换
 * @author zhanyi
 */

UE.plugin.register("searchreplace", function () {
    var me = this;

    var _blockElm = {table: 1, tbody: 1, tr: 1, ol: 1, ul: 1};

    var lastRng = null;

    function getText(node) {
        var text = node.nodeType == 3
            ? node.nodeValue
            : node[browser.ie ? "innerText" : "textContent"];
        return text.replace(domUtils.fillChar, "");
    }

    function findTextInString(textContent, opt, currentIndex) {
        var str = opt.searchStr;

        var reg = new RegExp(str, "g" + (opt.casesensitive ? "" : "i")),
            match;

        if (opt.dir == -1) {
            textContent = textContent.substr(0, currentIndex);
            textContent = textContent.split("").reverse().join("");
            str = str.split("").reverse().join("");
            match = reg.exec(textContent);
            if (match) {
                return currentIndex - match.index - str.length;
            }
        } else {
            textContent = textContent.substr(currentIndex);
            match = reg.exec(textContent);
            if (match) {
                return match.index + currentIndex;
            }
        }

        return -1;
    }

    function findTextBlockElm(node, currentIndex, opt) {
        var textContent,
            index,
            methodName = opt.all || opt.dir == 1 ? "getNextDomNode" : "getPreDomNode";
        if (domUtils.isBody(node)) {
            node = node.firstChild;
        }
        var first = 1;
        while (node) {
            textContent = getText(node);
            index = findTextInString(textContent, opt, currentIndex);
            first = 0;
            if (index != -1) {
                return {
                    node: node,
                    index: index
                };
            }
            node = domUtils[methodName](node);
            while (node && _blockElm[node.nodeName.toLowerCase()]) {
                node = domUtils[methodName](node, true);
            }
            if (node) {
                currentIndex = opt.dir == -1 ? getText(node).length : 0;
            }
        }
    }

    function findNTextInBlockElm(node, index, str) {
        var currentIndex = 0,
            currentNode = node.firstChild,
            currentNodeLength = 0,
            result;
        while (currentNode) {
            if (currentNode.nodeType == 3) {
                currentNodeLength = getText(currentNode).replace(
                    /(^[\t\r\n]+)|([\t\r\n]+$)/,
                    ""
                ).length;
                currentIndex += currentNodeLength;
                if (currentIndex >= index) {
                    return {
                        node: currentNode,
                        index: currentNodeLength - (currentIndex - index)
                    };
                }
            } else if (!dtd.$empty[currentNode.tagName]) {
                currentNodeLength = getText(currentNode).replace(
                    /(^[\t\r\n]+)|([\t\r\n]+$)/,
                    ""
                ).length;
                currentIndex += currentNodeLength;
                if (currentIndex >= index) {
                    result = findNTextInBlockElm(
                        currentNode,
                        currentNodeLength - (currentIndex - index),
                        str
                    );
                    if (result) {
                        return result;
                    }
                }
            }
            currentNode = domUtils.getNextDomNode(currentNode);
        }
    }

    function searchReplace(me, opt) {
        var rng = lastRng || me.selection.getRange(),
            startBlockNode,
            searchStr = opt.searchStr,
            span = me.document.createElement("span");
        span.innerHTML = "$$ueditor_searchreplace_key$$";

        rng.shrinkBoundary(true);

        //判断是不是第一次选中
        if (!rng.collapsed) {
            rng.select();
            var rngText = me.selection.getText();
            if (
                new RegExp(
                    "^" + opt.searchStr + "$",
                    opt.casesensitive ? "" : "i"
                ).test(rngText)
            ) {
                if (opt.replaceStr != undefined) {
                    replaceText(rng, opt.replaceStr);
                    rng.select();
                    return true;
                } else {
                    rng.collapse(opt.dir == -1);
                }
            }
        }

        rng.insertNode(span);
        rng.enlargeToBlockElm(true);
        startBlockNode = rng.startContainer;
        var currentIndex = getText(startBlockNode).indexOf(
            "$$ueditor_searchreplace_key$$"
        );
        rng.setStartBefore(span);
        domUtils.remove(span);
        var result = findTextBlockElm(startBlockNode, currentIndex, opt);
        if (result) {
            var rngStart = findNTextInBlockElm(result.node, result.index, searchStr);
            var rngEnd = findNTextInBlockElm(
                result.node,
                result.index + searchStr.length,
                searchStr
            );
            rng
                .setStart(rngStart.node, rngStart.index)
                .setEnd(rngEnd.node, rngEnd.index);

            if (opt.replaceStr !== undefined) {
                replaceText(rng, opt.replaceStr);
            }
            rng.select();
            return true;
        } else {
            rng.setCursor();
        }
    }

    function replaceText(rng, str) {
        str = me.document.createTextNode(str);
        rng.deleteContents().insertNode(str);
    }

    return {
        commands: {
            searchreplace: {
                execCommand: function (cmdName, opt) {
                    utils.extend(
                        opt,
                        {
                            all: false,
                            casesensitive: false,
                            dir: 1
                        },
                        true
                    );
                    var num = 0;
                    if (opt.all) {
                        lastRng = null;
                        var rng = me.selection.getRange(),
                            first = me.body.firstChild;
                        if (first && first.nodeType == 1) {
                            rng.setStart(first, 0);
                            rng.shrinkBoundary(true);
                        } else if (first.nodeType == 3) {
                            rng.setStartBefore(first);
                        }
                        rng.collapse(true).select(true);
                        if (opt.replaceStr !== undefined) {
                            me.fireEvent("saveScene");
                        }
                        while (searchReplace(this, opt)) {
                            num++;
                            lastRng = me.selection.getRange();
                            lastRng.collapse(opt.dir == -1);
                        }
                        if (num) {
                            me.fireEvent("saveScene");
                        }
                    } else {
                        if (opt.replaceStr !== undefined) {
                            me.fireEvent("saveScene");
                        }
                        if (searchReplace(this, opt)) {
                            num++;
                            lastRng = me.selection.getRange();
                            lastRng.collapse(opt.dir == -1);
                        }
                        if (num) {
                            me.fireEvent("saveScene");
                        }
                    }

                    return num;
                },
                notNeedUndo: 1
            }
        },
        bindEvents: {
            clearlastSearchResult: function () {
                lastRng = null;
            }
        }
    };
});
